home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
tools
/
czesc_1
/
cwtoy
/
src
/
cwtoy.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-20
|
34KB
|
1,053 lines
/* This program is a CW toy for sending morse code using two
* windows.
*
* Speech Toy was written by David M Lucas and that is what
* Rob Frohne started with to create CWToy. Thanks also to Rob Peck for his
* audiotools2.c without which this would probably never have
* been completed.
* If you find somthing you don't like, fix it! Have fun!
* Thanks Amiga. */
#include "cwtoy.h"
/* Revision number is used on calls to OpenLibrary
* to let the system know what revision level the
* program was written for. Usually refers to the
* ROM release number or the release number of a
* disk based library.
*/
#define Enable_Abort 1
#define REVISION 1
#define CONTWINDW 283 /* Overall Control Window Width/Height */
#define CONTWINDH 100
/* Pen numbers to draw gadget borders/images/text with */
#define REDP 3 /* color in register 3 once was red */
#define BLKP 2 /* color in register 2 was black */
#define WHTP 1 /* color in register 1 was white */
#define BLUP 0 /* color in register 0 was blue */
/* the length of the English and phonetic buffers */
#define NUMPROPS 4 /* number of proportional gadgets */
#define SPEEDSIZE 20 /* the number of digits in the speed */
#define StartChannel(c) ControlChannel(c, CMD_START)
#define StopChannel(c) ControlChannel(c, CMD_STOP)
/* Ranges of proportional data */
#define MAXWEIGHT 2000
#define MINWEIGHT 500
#define MAXSPEED 99
#define MINSPEED 3
#define MAXPITCH1 2000
#define MINPITCH1 100
#define RNGWEIGHT (MAXWEIGHT - MINWEIGHT) +1
#define RNGSPEED (MAXSPEED - MINSPEED) +1
#define RNGPITCH1 (MAXPITCH1 - MINPITCH1) +1
#define RNGVOL (MAXVOL - MINVOL) +1
#define NORMSPACING 1000
/*#define DEFWEIGHT 1000 */
/*#define DEFSPEED 20 */
/*#define DEFPITCH1 440 */
#define CIRQSIZE 4096
struct TextAttr TestFont = /* Needed for opening screen */
{
(STRPTR)"topaz.font",
TOPAZ_EIGHTY, 0, 0
};
struct Code {
int speed;
int pitch;
int volume;
int weight;
int spacing;
};
struct Code cw = {
20, 440, 64, 1000, 1000
};
USHORT circleq[CIRQSIZE]; /* This is the circlular Q buffer that will
* allow us to edit the buffer before it is
* sent if we desire. */
/* Initialize the circular Q pointers. */
int inptr = 0, outptr = 0;
int ctrls = 0;
/* String Gadgets *********************************************
* First the string gadgets.
* 1) because the Phonetic string is refreshed programaticly
* (that is, deleted and added again) quite often, and doing
* this requires the use of RefreshGadgets(), and this causes
* gadgets that are closer to the beginning of the list than
* the gadget given to RefreshGadgets() to flicker.
* 2) because they don't flicker when OTHER gadgets
* (ie female/male, coming up) are deleted and added.
*
* These'll be used to put a nice double line border around
* each of the two string gadgets.
*
* y,x pairs drawn as a connected line. Be sure to have an even
* number of arguments (ie complete pairs).
*/
SHORT StrVectors[] = {
0, 0, 160, 0, 160, 13, 0, 13,
0, 1, 159, 1, 159, 12, 1, 12,
1, 1
};
struct Border StrBorder = {
-4, -3, /* initial offsets, gadget relative */
WHTP, BLUP, JAM1, /* pens (fore, back) and drawmode */
9, /* number of vectors */
StrVectors, /* pointer to the actual array of vectors */
NULL /* no next Border, can point to another border */
};
/* The same undo buffer is used for both string gadgets,
* this is sized to largest so that largest fits.
*/
UBYTE UndoBuffer[SPEEDSIZE];
/* Speed Gadget is where the speed will be displayed. */
/* default text */
UBYTE Speed[SPEEDSIZE] = "20 Words per Minute";
UBYTE Space[2] = " ";
struct StringInfo EnglInfo = {
Speed, /* pointer to I/O buffer */
UndoBuffer, /* pointer to undo buffer */
0, /* buffer position */
SPEEDSIZE, /* max number of chars, including NULL */
0, 0, /* first char in display, undo positions */
20, /* number of chars (currently) in the buffer */
0, 0, 0, /* position variables calculated by Intuition */
NULL, /* no pointer to RastPort */
0, /* not a LongInt string gadget */
NULL /* no pointer to alternate keymap */
};
struct IntuiText EnglText = {
WHTP, BLUP, /* FrontPen, BackPen */
JAM1, /* DrawMode */
0, -13, /* LeftEdge, TopEdge (relative to gadget) */
&TestFont, /* pointer to TextFont */
(UBYTE *) "Speed:", /* pointer to Text */
NULL /* no pointer to NextText */
};
struct Gadget SpeedGadget = {
NULL, /* pointer to Next Gadget */
11, 63, 290, 10, /* (Left Top Width Height) Hit Box */
GADGHCOMP, /* Flags */
RELVERIFY, /* Activation flags */
STRGADGET, /* Type */
(APTR)&StrBorder, /* pointer to Border Image */
NULL, /* no pointer to SelectRender */
&EnglText, /* pointer to GadgetText */
0, /* no MutualExclude */
(APTR)&EnglInfo, /* pointer to SpecialInfo */
0, /* no ID */
NULL /* no pointer to special data */
};
/* Now the proportional gadgets. */
/* Proportional Gadgets **************************************/
/* The following variables are used to create proportional
* Gadgets. These variables will be filled in with copies of
* the generic Gadgetry below.
*/
SHORT PropCount = 0; /* index to next available Gadget */
struct IntuiText PTexts[NUMPROPS];/* get copies of TPropText */
/* dummy AUTOKNOB Images are required */
struct Image PImages[NUMPROPS];
/* These get copies of TPropInfo */
struct PropInfo PInfos[NUMPROPS];
/* These get copies of TPropGadget */
struct Gadget Props[NUMPROPS];
struct IntuiText TPropText = {
WHTP, BLUP, /* FrontPen, BackPen */
JAM1, /* DrawMode */
0, -10, /* LeftEdge, TopEdge (relative to gadget) */
&TestFont, /* pointer to TextFont */
NULL, /* pointer to Text is filled at runtime */
NULL /* no pointer to NextText */
};
struct PropInfo TPropInfo = {
AUTOKNOB | FREEHORIZ, /* Flags */
0, 0, /* Pots: Horiz, Vert: both start at 0 */
0x1FFF, 0x1FFF, /* Bodies: Horiz is 1/8, Vert is 1/8 */
0, 0, 0, 0, 0, 0 /* System usage stuff */
};
/* this is the template for the Gadget of a horizontal */
/* Proportional Gadget */
struct Gadget TPropGadget = {
&SpeedGadget, /* pointer to NextGadget */
7, 12, 115, 10, /* Select Box L T W H */
GADGHCOMP | GADGIMAGE, /* Flags */
GADGIMMEDIATE | RELVERIFY, /* Activation flags */
PROPGADGET, /* Type */
NULL, /* pointer to Image filled in later */
NULL, /* no pointer to SelectRender */
NULL, /* no pointer to GadgetText */
0, /* no MutualExclude */
NULL, /* SpecialInfo proportional data filled later */
0, /* no ID */
NULL /* no pointer to special data */
};
struct IntuitionBase *IntuitionBase = 0;
struct GfxBase *GfxBase = 0;
/* Only one menu. */
ULONG MenuNumber;
ULONG TheMenu;
ULONG TheItem;
struct IntuiText MenuItemText = {
BLUP, /* Front Pen */
WHTP, /* Back pen */
JAM2, /* Draw Mode */
0, /* Left Edge */
0, /* Top */
&TestFont, /* pointer to TextFont */
(UBYTE *) "About CW Toy...", /* text */
NULL /* next */
};
struct MenuItem MyMenuItem = {
NULL, /* pointer to next item */
0, /* left */
0, /* top */
150, /* width */
8, /* height */
ITEMTEXT | ITEMENABLED | HIGHCOMP, /* flags */
0, /* no mutual exclude */
(APTR)&MenuItemText, /* Render */
NULL, /* pointer to alternate image */
NULL, /* Command "amiga" char */
NULL, /* Sub Item */
MENUNULL /* nextselect */
};
struct Menu MyMenu = {
NULL, /* pointer to next menu */
0,0,150,0, /* left,0,Width,0 */
MENUENABLED, /* flags */
(BYTE *) "CW Toy Menu", /* menu name */
&MyMenuItem /* First Item in list */
};
struct IntuiText ReqText1 = {
BLUP, /* Front Pen */
WHTP, /* Back pen */
JAM2, /* Draw Mode */
5, /* Left Edge */
23, /* Top */
&TestFont, /* pointer to TextFont */
(UBYTE *) "Version 1.0 30 June, 1991", /* text */
NULL /* next */
};
struct IntuiText ReqText2 = {
BLUP, /* Front Pen */
WHTP, /* Back pen */
JAM2, /* Draw Mode */
5, /* Left Edge */
13, /* Top */
&TestFont, /* pointer to TextFont */
(UBYTE *) "Freeware - Public Domain ", /* text */
&ReqText1 /* next */
};
struct IntuiText ReqText3 = {
BLUP, /* Front Pen */
WHTP, /* Back pen */
JAM2, /* Draw Mode */
5, /* Left Edge */
3, /* Top */
&TestFont, /* pointer to TextFont */
(UBYTE *) "By Rob Frohne (KL7NA)", /* text */
&ReqText2 /* next */
};
struct IntuiText OKIText = {
BLUP, WHTP, /* FrontPen, BackPen */
JAM2, /* DrawMode */
6, 3, /* LeftEdge, TopEdge (relative to gadget) */
&TestFont, /* pointer to TextFont */
(UBYTE *) "OK", /* pointer to Text */
NULL /* no pointer to NextText */
};
struct Requester *AboutRequester;
USHORT autoret;
struct Window *ControlWindow = NULL;
struct IntuiMessage *MyIntuiMessage;
struct NewWindow NewControlWindow = {
00, 11, /* start LeftEdge, TopEdge */
CONTWINDW, CONTWINDH, /* start Width, Height */
-1, -1, /* DetailPen, BlockPen */
GADGETUP | CLOSEWINDOW | MENUPICK
| VANILLAKEY, /* IDCMP FLAGS */
WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE
| GIMMEZEROZERO | ACTIVATE,/* Flags (can be NULL) */
&Props[NUMPROPS-1], /* Pointer to FirstGadget */
NULL, /* no pointer to first CheckMark */
(UBYTE *) "CW Toy", /* Title (can be NULL) */
NULL, /* no Pointer to Screen */
NULL, /* no Pointer to BitMap */
20, 20, /* Min/max Sizable to (w/h) */
CONTWINDW, CONTWINDH, /* These aint used, can't size */
WBENCHSCREEN /* Type of screen window appears in */
};
struct NewWindow NewDisplayWindow = {
00,(CONTWINDH + 10),
CONTWINDW,50,
-1,-1,
MENUPICK|VANILLAKEY, /* IDCMP FLAGS */
GIMMEZEROZERO|ACTIVATE|WINDOWSIZING|WINDOWDEPTH|WINDOWDRAG|REFRESHWINDOW,
0,
NULL,
(UBYTE *) "CW Buffer",
NULL,
NULL,
10,10,700,440,
WBENCHSCREEN };
/* Some audio stuff for Rob Peck's Audio Tools. */
extern char *w1;
extern int ControlChannel();
extern struct MsgPort *InitAudio();
struct MsgPort *myport; /* CHANGE from article */
LONG channel;
/* Some stuff for the Console. */
extern struct ConIOBlocks *CreateConsole();
struct ConIOBlocks *cio;
struct Window *DisplayWindow, *OpenWindow();
/** start of code ***************************/
main( argc, argv )
int argc;
char *argv[];
{
ULONG Signals; /* Wait() tells me which to look at */
ULONG MIClass; /* Save quickly, ReplyMsg() asap */
USHORT MICode;
APTR MIAddress;
LONG error;
int i,j,k,goaway = 0;
char numspeed[SPEEDSIZE];
FILE *fp, *fopen();
fp = 0; /* Initialize fp */
/* check for a question mark as the first argument */
if ( argv[1][0] == '?' ) {
printf("Usage: %s [message] [-f filename] [-e] [-s speed] [-p pitch] [-v volume] [-w weighting]\n [-b spaceing]\n", argv[0] );
exit(0);
} /* end of checking for a question mark */
/* Parse the input line */
for ( i=1; i < argc; i++ ) {
/* see if it starts with a minus (then s,p,v,w,f) */
if ( argv[i][0] != '-' ) {
/* Get the message if it is there. */
for ( j=0; argv[i][j] != '\0'; j++ )
circleq[inptr++] = argv[i][j];
circleq[inptr++] = 0x20;
}
else {
/* Parse the switches. */
switch( argv[i][1] ) {
case 'f' : /* File to send. */
if ((fp = fopen(argv[++i],"r")) == NULL) {
printf("cwtoy: can't open %s\n",argv[++i]);
exit(1);
}
break;
case 'e' : /* Exit after sending message of file. */
goaway = 1;
break;
case 's' : /* Speed */
cw.speed = atoi(argv[++i]);
ftoa((double)cw.speed,numspeed,0,1);
if(cw.speed < 10) strcat(numspeed,Space);
strcat(numspeed,(Speed + 2));
strcpy(Speed,numspeed);
break;
case 'p' : /* Pitch */
cw.pitch = atoi(argv[++i]);
break;
case 'v' : /* Volume */
cw.volume = atoi(argv[++i]);
break;
case 'w' : /* Weighting */
cw.weight = atoi(argv[++i]);
break;
case 'b' : /* Spacingfactor */
cw.spacing = atoi(argv[++i]);
break;
default :
printf("Usage: %s [message] [-f filename] [-e] [-s speed] [-p pitch] [-v volume] [-w weighting]\n [-b spaceing]\n", argv[0] );
exit(0);
break;
} /* end of switch for the arguments */
} /* end of checking for a switch argument */
}
/* First initialize the audio routines using Rob Peck's Audio Tools. */
myport = InitAudio(); /* now returns address of message port */
if(myport == 0)
{
printf("Problem in InitAudio!\n");
MyCleanup();
}
{
channel = GetChannel(-1);
if(channel == -1)
{
printf("cannot get a channel!\n");
MyCleanup();
}
error = StopChannel(channel);
if(error)
{
printf("error in stopping channel = %ld\n",error);
MyCleanup();
}
}
/* Open those libraries that the program uses directly */
if ((IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", REVISION)) == 0) {
MyCleanup();
exit(1);
}
if ((GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library", REVISION)) == 0) {
MyCleanup();
exit(1);
}
/* This is where the proportional gadgets are set up, using
* the templates that were declared staticly.
*/
for(PropCount = 0; PropCount < NUMPROPS; PropCount++) {
PTexts[PropCount] = TPropText;
Props[PropCount] = TPropGadget;
PInfos[PropCount] = TPropInfo;
Props[PropCount].GadgetText = (struct IntuiText *)
&PTexts[PropCount];
Props[PropCount].GadgetRender = (APTR)
&PImages[PropCount];
Props[PropCount].SpecialInfo = (APTR)&PInfos[PropCount];
switch (PropCount) {
case 0:
PTexts[PropCount].IText = (UBYTE *) "Weighting:";
if (cw.weight == MAXWEIGHT)
PInfos[PropCount].HorizPot = 65535;
else
PInfos[PropCount].HorizPot = ((cw.weight - MINWEIGHT)
<< 16) / (MAXWEIGHT - MINWEIGHT);
break;
case 1:
PTexts[PropCount].IText = (UBYTE *) "Speed:";
Props[PropCount].TopEdge += 22;
Props[PropCount].NextGadget = &Props[PropCount-1];
if (cw.speed == MAXSPEED )
PInfos[PropCount].HorizPot = 65535;
else
PInfos[PropCount].HorizPot = ((cw.speed - MINSPEED)
<< 16) / (MAXSPEED - MINSPEED);
break;
case 2:
PTexts[PropCount].IText = (UBYTE *) "Pitch:";
Props[PropCount].LeftEdge += 145;
Props[PropCount].NextGadget = &Props[PropCount-1];
if (cw.pitch == MAXPITCH1)
PInfos[PropCount].HorizPot = 65535;
else
PInfos[PropCount].HorizPot = ((cw.pitch - MINPITCH1)
<< 16) / (MAXPITCH1 - MINPITCH1);
break;
case 3:
PTexts[PropCount].IText = (UBYTE *) "Volume:";
Props[PropCount].TopEdge += 22;
Props[PropCount].LeftEdge += 145;
Props[PropCount].NextGadget = &Props[PropCount-1];
if (cw.volume == MAXVOL)
PInfos[PropCount].HorizPot = 65535;
else
PInfos[PropCount].HorizPot = ((cw.volume - MINVOL)
<< 16) / (MAXVOL - MINVOL);
break;
default:
break;
}
}
if ((ControlWindow = (struct Window *)OpenWindow
(&NewControlWindow)) == NULL) {
MyCleanup();
exit(1);
}
if ((DisplayWindow = OpenWindow(&NewDisplayWindow)) == NULL) {
MyCleanup();
exit(1);
}
if ((cio=CreateConsole(DisplayWindow)) == 0) {
MyCleanup();
}
/* fill background of window */
SetAPen(ControlWindow->RPort, BLKP);
RectFill(ControlWindow->RPort,0L,0L,
(LONG)ControlWindow->GZZWidth, (LONG)ControlWindow->GZZHeight);
RefreshGadgets(&Props[NUMPROPS-1],ControlWindow,NULL);
SetMenuStrip(ControlWindow, &MyMenu);
SetMenuStrip(DisplayWindow, &MyMenu);
if (fp != 0) { /* If we opened a file to send, send it first! */
filesend(fp);
if (goaway == 1) {
MyCleanup();
exit(0);
}
}
if (inptr > 0) send(); /* Got a -m message to start already! */
/* !!! Ah, But what if Control Window's not been opened? */
/* Rob changed some tricky stuff here! */
for (;;) { /* ever wait for a signal and process it */
/* wait lets the rest of the system run, */
/* this program sleeps */
Signals = Wait((1 << myport->mp_SigBit) |
(1 << DisplayWindow->UserPort->mp_SigBit) |
(1 << ControlWindow->UserPort->mp_SigBit));
/* now check to see to what we owe the intrusion */
Chk_Abort();
if (Signals & (1<< myport->mp_SigBit)) {
if(MayGetNote(myport,FALSE) == 1L) {
++outptr % CIRQSIZE; /* Always increment the outptr after we are
* done sending a character. */
/* If not caught up and no pause in effect, send the next one. */
if (inptr != outptr) {
if (ctrls == 0) send();
}
else {
if (goaway == 1) {
MyCleanup();
exit(0);
}
}
}
}
if (Signals & (1<< ControlWindow->UserPort->mp_SigBit)) {
/* Process the Intuition message */
while (MyIntuiMessage=(struct IntuiMessage *)
GetMsg(ControlWindow->UserPort)) {
/* Get all the needed info and give message back */
MIClass = MyIntuiMessage->Class;
MICode = MyIntuiMessage->Code;
MIAddress = MyIntuiMessage->IAddress;
ReplyMsg(MyIntuiMessage);
/* Now, what was it you wanted? */
switch (MIClass) {
case VANILLAKEY:
/* Service the character buffer. */
switch(qUp(MICode)) {
case 0:
/* If we are caught up
* initialize the sending.
* (Remember that qUp
* incremented inptr.) */
if((inptr % CIRQSIZE == (outptr + 1) % CIRQSIZE)
&& (ctrls == 0))
send();
break;
case 1:
/* Check for Control C. */
exit(0);
case 2:
case 3:
case 4:
break;
}
break;
case MENUPICK:
menumessage(MICode, ControlWindow);
break;
case GADGETUP: /* reply, then process */
gadgetmessage(MIAddress, ControlWindow);
break;
case CLOSEWINDOW: /* bye! */
while (MyIntuiMessage = (struct
IntuiMessage *) GetMsg(ControlWindow->UserPort))
ReplyMsg(MyIntuiMessage);
MyCleanup();
exit(0);
default:
break;
} /* switch */
} /* while */
} /* if */
if (Signals & (1<< DisplayWindow->UserPort->mp_SigBit)) {
/* Process the Intuition message */
while (MyIntuiMessage=(struct IntuiMessage *)
GetMsg(DisplayWindow->UserPort)) {
/* Get all the needed info and give message back */
MIClass = MyIntuiMessage->Class;
MICode = MyIntuiMessage->Code;
MIAddress = MyIntuiMessage->IAddress;
ReplyMsg(MyIntuiMessage);
/* Now, what was it you wanted? */
switch (MIClass) {
case VANILLAKEY:
/* Service the character buffer. */
/* For comments see similar section under ControlWindow. */
switch(qUp(MICode)) {
case 0:
if((inptr % CIRQSIZE == (outptr + 1) % CIRQSIZE)
&& (ctrls == 0))
send();
break;
case 1:
exit(0);
case 2:
case 3:
case 4:
break;
}
break;
case MENUPICK:
menumessage(MICode, DisplayWindow);
break;
default:
break;
} /* switch */
} /* while */
} /* if */
}/* for */
} /* main */
/* a MENUPICK has been received, this
* routine takes the appropriate action
*/
menumessage(code, w)
USHORT code;
struct Window *w;
{
switch (MENUNUM(code)) {
case 0:
switch (ITEMNUM(code)) {
case 0:
AutoRequest(w, &ReqText3, NULL,
&OKIText, 0, 0, 280, 47);
break;
}
break;
}
return(0);
}
/* a GADGETUP has been received, this
* routine takes the appropriate action
*/
gadgetmessage(address, w)
APTR address;
struct Window *w;
{
long PropRange;
UBYTE i;
int length;
char numspeed[SPEEDSIZE];
if (address == (APTR)&Props[2]) {
PropRange = RNGPITCH1;
cw.pitch = (((PInfos[2].HorizPot >> 1)
* PropRange) >> 15) + MINPITCH1;
}
else if (address == (APTR)&Props[3]) {
PropRange = RNGVOL;
cw.volume = (((PInfos[3].HorizPot >> 1)
* PropRange) >> 15) + MINVOL;
}
else if (address == (APTR)&Props[0]) {
PropRange = RNGWEIGHT;
cw.weight = (( (PInfos[0].HorizPot >> 1)
* PropRange) >> 15) + MINWEIGHT;
}
/* Since the program changes the contents of the string
* gadgets' buffer and it's size, which is something else
* intuition doesn't expect a program (as opposed to the
* user) to do. The program must remove, then change, then
* add this gadget, and then by passing the address of this
* gadget to RefreshGadgets(), only the gadgets from here
* to the start of the list will be refreshed, which
* minimizes the visible flash that RefreshGadgets() can
* introduce.
*/
else if (address == (APTR)&Props[1]) {
PropRange = RNGSPEED ;
cw.speed = (((PInfos[1].HorizPot >> 1)
* PropRange) >> 15) + MINSPEED;
i = RemoveGadget(ControlWindow, &SpeedGadget);
/* if((length = stci_d(numspeed, cw.speed)) < 4)
{
if(length < 3) strcat(numspeed,Space);
strcat(numspeed,(Speed + 2));
strcpy(Speed,numspeed);
} */ /* This was commented out to modify it to Manx. */
/* The 3 lines below were added to make it Manx compatible. */
ftoa((double)cw.speed,numspeed,0,1);
if(cw.speed < 10) strcat(numspeed,Space);
strcat(numspeed,(Speed + 2));
strcpy(Speed,numspeed);
/* The 3 lines above this were added to make it Manx compatible. */
AddGadget(ControlWindow, &SpeedGadget, i);
RefreshGadgets(&SpeedGadget, ControlWindow, NULL);
}
return(0);
}
/* Deallocate any memory, and close all of the
* windows/screens/devices/libraries in reverse order to
* make things work smoothly. And be sure to check
* that the open/allocation was successful before
* closing/deallocating.
*/
MyCleanup()
{
FinishAudio(myport); /* NEW parameter for FinishAudio */
if (myport != 0)
DeletePort(myport);
if (cio != 0)
DeleteConsole(cio);
if (DisplayWindow != NULL)
CloseWindow(DisplayWindow);
if (ControlWindow != NULL)
CloseWindow(ControlWindow);
/* freeimages makes sure image allocation was successful */
if (GfxBase != 0)
CloseLibrary(GfxBase);
if (IntuitionBase != 0)
CloseLibrary(IntuitionBase);
return(0);
}
UBYTE Lookup[] = {0x01, 0x6, 0x11, 0x15, 0x09, 0x02, 0x14, 0x0b, 0x10, 0x04, 0x1e,
0x0d, 0x12, 0x07, 0x05, 0x0f, 0x16, 0x1b, 0x0a, 0x08, 0x03, 0x0c, 0x18,
0x0e, 0x19, 0x1d, 0x13, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x52, 0x01, 0xc8,
0x01, 0x01, 0x5d, 0x2d, 0x6d, 0x22, 0x2a, 0x73, 0x61, 0x6a, 0x29, 0x3f, 0x3e, 0x3c,
0x38, 0x30, 0x20, 0x21, 0x23, 0x27, 0x2f, 0x47, 0x55, 0x01, 0x31, 0x01, 0x4c,
0x01, 0x06, 0x11, 0x15, 0x09, 0x02, 0x14, 0x0b, 0x10, 0x04, 0x1e,
0x0d, 0x12, 0x07, 0x05, 0x0f, 0x16, 0x1b, 0x0a, 0x08, 0x03, 0x0c, 0x18,
0x0e, 0x19, 0x1d, 0x13, 0x2d, 0x29, 0x6d, 0x01, 0xac, 0x01,
0x06, 0x11, 0x15, 0x09, 0x02, 0x14, 0x0b, 0x10, 0x04, 0x1e,
0x0d, 0x12, 0x07, 0x05, 0x0f, 0x16, 0x1b, 0x0a, 0x08, 0x03, 0x0c, 0x18,
0x0e, 0x19, 0x1d, 0x13, 0x2d, 0x29, 0x6d, 0x01, 0x01};
int qUp(letter)
/* qUp is the only place that inptr should ever change! */
USHORT letter;
{
char buffer[1];
/* Check for backspace and that we can backup. */
if( (letter == 0x08) && (inptr % CIRQSIZE != (outptr + 1) % CIRQSIZE)
&& (inptr != outptr)
&& (inptr % CIRQSIZE != (outptr -1) % CIRQSIZE) ) {
(--inptr) % CIRQSIZE;
/*(--inptr) % CIRQSIZE;*/
buffer[0] = (char)(letter & 0xff); /* Backspace in the
* DisplayWindow. */
if(letter != 0x9b) WriteConsole(cio,buffer,1);
return(2);
}
/* Check for Control C. If so, blow it away. */
else if(letter == 0x03) {
MyCleanup();
return(1);
}
/* Control S will pause the sending and control Q
* will resume it where it left off. */
/* Control S */
else if(letter == 0x13) {
ctrls = 1;
return(2);
}
/* Control Q */
else if(letter == 0x11) {
ctrls = 0;
if(inptr != outptr) send();
return(2);
}
/* Check for Control X. If so clear the circlular Q. */
else if(letter == 0x18) {
/* How do we handle the wrap around? */
while (inptr % CIRQSIZE != (outptr + 1) % CIRQSIZE) {
(--inptr) % CIRQSIZE;
buffer[0] = (char)(0x08 & 0xff);
if(letter != 0x9b) WriteConsole(cio,buffer,1);
}
return(2);
}
/* Make the return key have no effect. */
else if(letter == 0x0d) return(3);
/* Main Circular Character Storage. */
/* Make sure that the inptr doesn't catch up with the outptr *
* If it doesn't stow it in the buffer and print it in the *
* display window. */
else if(((inptr + 1) % CIRQSIZE != outptr % CIRQSIZE)
&& (letter != 0x08)) {
circleq[inptr] = letter;
buffer[0] = (char)(letter & 0xff);
if(letter != 0x9b) WriteConsole(cio,buffer,1);
(++inptr) % CIRQSIZE; /* increment the inptr so the *
* next character will go in *
* the right place. */
return(0);
}
/* If the circular Q is full... */
else if((inptr + 1) % CIRQSIZE == outptr % CIRQSIZE) {
DisplayBeep(NULL); /* Flash the display. */
printf("Circular Q buffer is full!\n");
return(2);
}
/* The default (maybe the operator wanted to backspace but wasn't
* quick enough) or .... */
else
/*(--inptr) % CIRQSIZE;*/
return(3);
}
send()
/* Sends one letter at a time gotten from the user after the file has
* been sent of one was. */
{
long error;
UBYTE inproc; /* Pattern in process of being sent. */
inproc = Lookup[circleq[outptr]];
if(circleq[outptr] == 32) space();
while((inproc) != 1){
if(01 & inproc) dah();
else dit();
inproc >>= 1;
}
charspace();
error = StartChannel(channel);
if(error)
{
printf("error starting channel = %ld\n",error);
MyCleanup();
}
return(0);
}
dit()
{
PlayFreq(channel,cw.pitch,w1,cw.volume,(LONG)(1200/cw.speed),0L,0L,0L);
PlayFreq(channel,cw.pitch,w1,0L,(LONG)(1200/cw.speed),0L,0L,0L);
return(0);
}
dah()
{
PlayFreq(channel,cw.pitch,w1,cw.volume,
(LONG)(3600*cw.weight/1000/ cw.speed),0L,0L,0L);
PlayFreq(channel,cw.pitch,w1,0L,(LONG)(1200/cw.speed),0L,0L,0L);
return(0);
}
space()
{
PlayFreq(channel,cw.pitch,w1,0L,
(LONG)(4800*cw.spacing/NORMSPACING/cw.speed),0L,0L,0L);
return(0);
}
charspace()
{
PlayFreq(channel,(LONG)cw.pitch,w1,0L,
(LONG)(2400*cw.spacing/NORMSPACING/cw.speed),0L,myport,1L);
return(0);
}
filesend(fp)
FILE *fp;
{
ULONG Signals; /* Wait() tells me which to look at */
ULONG MIClass; /* Save quickly, ReplyMsg() asap */
USHORT MICode;
APTR MIAddress;
LONG error;
int letter;
UBYTE inproc; /* Pattern in process of being sent. */
while((letter = getc(fp)) != EOF) {
Chk_Abort();
inproc = Lookup[letter];
if (letter == 0x0a) inproc = 0x01;
if(letter == 32) space();
while((inproc) != 1){
if(01 & inproc) dah();
else dit();
inproc >>= 1;
}
charspace();
if (error = StartChannel(channel))
{
printf("error starting channel = %ld\n",error);
MyCleanup();
}
nosend:
/* Wait lets the rest of the system run,
* while this program sleeps. */
Signals = Wait((1 << myport->mp_SigBit) |
(1 << DisplayWindow->UserPort->mp_SigBit) |
(1 << ControlWindow->UserPort->mp_SigBit));
/* now check to see to what we owe the intrusion */
if (Signals & (1<< myport->mp_SigBit)) {
MayGetNote(myport,FALSE);
}
if (Signals & (1<< ControlWindow->UserPort->mp_SigBit)) {
/* Process the Intuition message */
while (MyIntuiMessage=(struct IntuiMessage *)
GetMsg(ControlWindow->UserPort)) {
/* Get all the needed info and give message back */
MIClass = MyIntuiMessage->Class;
MICode = MyIntuiMessage->Code;
MIAddress = MyIntuiMessage->IAddress;
ReplyMsg(MyIntuiMessage);
/* Now, what was it you wanted? */
switch (MIClass) {
case VANILLAKEY: /* We are accepting no input for sending
* from the Display Window. */
switch(MICode) {
case 0x03: /* Control C */
MyCleanup();
exit(0);
case 0x18: /* Control X */
goto finishfile;
case 0x13: /* Control S */
ctrls = 1;
break;
case 0x11: /* Control Q */
ctrls = 0;
break;
default:
break;
}
break;
case MENUPICK:
menumessage(MICode, ControlWindow);
break;
case GADGETUP: /* reply, then process */
gadgetmessage(MIAddress, ControlWindow);
break;
case CLOSEWINDOW: /* bye! */
while (MyIntuiMessage = (struct
IntuiMessage *) GetMsg(ControlWindow->UserPort))
ReplyMsg(MyIntuiMessage);
MyCleanup();
exit(0);
break;
default:
break;
} /* switch */
} /* while */
} /* if */
if (Signals & (1<< DisplayWindow->UserPort->mp_SigBit)) {
/* Process the Intuition message */
while (MyIntuiMessage=(struct IntuiMessage *)
GetMsg(DisplayWindow->UserPort)) {
/* Get all the needed info and give message back */
MIClass = MyIntuiMessage->Class;
MICode = MyIntuiMessage->Code;
MIAddress = MyIntuiMessage->IAddress;
ReplyMsg(MyIntuiMessage);
/* Now, what was it you wanted? */
switch (MIClass) {
case VANILLAKEY: /* We are accepting no input for sending
* from the Display Window. */
switch(MICode) {
case 0x03: /* Control C */
MyCleanup();
exit(0);
case 0x18: /* Control X */
goto finishfile;
case 0x13: /* Control S */
ctrls = 1;
break;
case 0x11: /* Control Q */
ctrls = 0;
break;
default:
break;
}
break;
case MENUPICK:
menumessage(MICode, DisplayWindow);
break;
default:
break;
} /* switch */
} /* while */
} /* if */
if (ctrls == 1) goto nosend;
} /* while */
finishfile:
fclose(fp);
ctrls = 0;
PlayFreq(channel,(LONG)cw.pitch,w1,0L,(LONG)(2400/cw.speed),0L,myport,2L);
if (error = StartChannel(channel)) {
printf("error starting channel = %ld\n",error);
MyCleanup();
}
for(;;) { /* Wait until the entire file has been sent. */
if(MayGetNote(myport,TRUE) == 2L) return(0);
}
return(0);
}
_abort()
{
MyCleanup();
exit(0);
}